package com.qk.management.aop;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.qk.vo.portal.PortalVO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

/**
 *
 * @author lyl
 * @created 2025/10/17 11:40
 * @description
 *
 */

@Slf4j
@Aspect  // 声明当前类为切面类
@Component
public class TimeCountAspect {
    @Autowired
    private StringRedisTemplate redisClient;


    // 定义切点方法： public、无参数、无返回值、空方法体、方法名任意
    // @Pointcut
    // value 支持2种切点表达式 ①execution ②@annotation [重点]
    // 告诉AOP 哪些方法需要被拦截增强
    @Pointcut(value = "execution(* com.qk.management.service.*.*(..))")
    public void pt() {
    }
    @Pointcut(value = "execution(* com.qk.management.service.impl.ReportOverviewServiceImpl.*(..))")
    public void ptRedis(){
    }

    // 通知方法： 告诉AOP 在切点方法执行之前和之后执行通知方法 增强具体内容
    @Around("pt()")
    public Object timeCount(ProceedingJoinPoint pjp) throws Throwable {
        // 获取开始时间毫秒值
        long start = System.currentTimeMillis();
        // 执行拦截方法 (通过反射执行拦截方法)
        Object proceed = pjp.proceed();
        // 获取结束时间毫秒值
        long end = System.currentTimeMillis();

        // 获取类名、获取方法名
        String className = pjp.getTarget().getClass().getName();
        // 获取方法名
        String methodName = pjp.getSignature().getName();
        log.info("{}中方法名{}耗时：{}",className,methodName, (end - start));
        return proceed;
    }
    @Around("ptRedis()")
    public Object timeCountRedis(ProceedingJoinPoint pjp) throws Throwable {
        String key = "qk:portal:reportOverview";
        try {
            String value = redisClient.opsForValue().get(key);
            if (ObjectUtil.isNotEmpty(value)){
                return JSONUtil.toBean(value, PortalVO.class);
            }
        }catch (Exception e){
            log.error("redis查询报表总览异常{}", e.getMessage());
        }
        Object proceed = pjp.proceed();
        try {
            redisClient.opsForValue().set(key, JSONUtil.toJsonStr(proceed));

        }catch (Exception e){
            log.error("redis保存报表总览异常{}", e.getMessage());
        }
        // 获取类名、获取方法名
        String className = pjp.getTarget().getClass().getName();
        // 获取方法名
        String methodName = pjp.getSignature().getName();
        log.info("-----redis-------{}中方法名{}执行了",className,methodName);
        return proceed;
    }
}
